<?php
/**
 * 计算utf8字符长度
 * @param $s
 * @return false|int
 */
function str_utf8_strlen($s)
{
    return mb_strlen($s, 'UTF-8');
}

/**
 * 截取utf8编码的字符串
 * @param $s
 * @param $start
 * @param $len
 * @return string
 */
function str_utf8_substr($s, $start, $len)
{
    return mb_substr($s, $start, $len, 'UTF-8');
}


/**
 * 增强版 截取字符串，支持多语言，例如中文
 * @param string $string
 * @param int $offset 非负，从0计数
 * @param string $length 截取长度
 * @return string $string
 * @example str_slice($chinese , 0, 5);
 */
function str_slice($string, $offset = 0, $length = '')
{
    if ('' == $length) {
        $length = $offset;
        $offset = 0;
    }
    if (function_exists('mb_substr')) return mb_substr($string, $offset, $length, 'utf-8');

    preg_match_all("/./su", $string, $data);

    return join("", array_slice($data[0], $offset, $length));
}

/**
 * 让 str_replace() 只替换一次
 * @param string $needle 将要被替换的内容
 * @param string $replace 替换后的内容
 * @param string $haystack 需要处理的内容
 * @return mixed 需要处理的内容
 */
function str_replace_once($needle, $replace, $haystack)
{
    $pos = strpos($haystack, $needle);
    if ($pos === false) return $haystack;
    return substr_replace($haystack, $replace, $pos, strlen($needle));
}

/**
 * 去除代码中的空白和注释
 * @param string $content 代码内容
 * @return string
 */
function str_strip_php_whitespace($content)
{
    $stripStr = '';
    //分析php源码
    $tokens = token_get_all($content);
    $last_space = false;
    for ($i = 0, $j = count($tokens); $i < $j; $i++) {
        if (is_string($tokens[$i])) {
            $last_space = false;
            $stripStr .= $tokens[$i];
        } else {
            switch ($tokens[$i][0]) {
                //过滤各种PHP注释
                case T_COMMENT:
                case T_DOC_COMMENT:
                    break;
                //过滤空格
                case T_WHITESPACE:
                    if (!$last_space) {
                        $stripStr .= ' ';
                        $last_space = true;
                    }
                    break;
                case T_START_HEREDOC:
                    $stripStr .= "<<<HEREDOC\n";
                    break;
                case T_END_HEREDOC:
                    $stripStr .= "HEREDOC;\n";
                    for ($k = $i + 1; $k < $j; $k++) {
                        if (is_string($tokens[$k]) && $tokens[$k] == ';') {
                            $i = $k;
                            break;
                        } else if ($tokens[$k][0] == T_CLOSE_TAG) {
                            break;
                        }
                    }
                    break;
                default:
                    $last_space = false;
                    $stripStr .= $tokens[$i][1];
            }
        }
    }
    return $stripStr;
}


/**
 * 删除php源码中的注释
 * @param string $content
 * @return string
 */
function str_strip_php_comment($content)
{
    $stripStr = '';
    //分析php源码
    $tokens = token_get_all($content);

    for ($i = 0, $j = count($tokens); $i < $j; $i++) {
        if (is_string($tokens[$i])) {

            $stripStr .= $tokens[$i];
        } else {
            switch ($tokens[$i][0]) {
                //过滤各种PHP注释
                case T_COMMENT:
                case T_DOC_COMMENT:
                    break;

                default:
                    $stripStr .= $tokens[$i][1];
            }
        }
    }
    return $stripStr;
}

/**
 * 去除html空格与换行
 * @param $content
 * @return string|string[]|null
 */
function str_strip_html_whitespace($content)
{
    $find = array("~>\s+<~", "~>(\s+\n|\r)~");
    $replace = array('><', '>');

    return preg_replace($find, $replace, $content);
}

/**
 * 裁剪字符串，支持中文
 * @param $str
 * @param int $length
 * @param int $start
 * @return string
 */
function str_cut($str, $length = 250, $start = 0)
{
    $charset = 'utf-8';
    if (function_exists("mb_substr")) {
        if (mb_strlen($str, $charset) <= $length) return $str;
        $slice = mb_substr($str, $start, $length, $charset);
    } else {
        $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        if (count($match[0]) <= $length) return $str;
        $slice = join("", array_slice($match[0], $start, $length));
    }
    return $slice;
}

/**
 * 转义html，使其正常显示在html页面
 * @param $html
 * @return string|string[]|null
 */
function str_html2text($html)
{
    $html = preg_replace("/(\<(.*)>)/Ui", '', $html);
    $html = str_replace('<', '&lt;', $html);
    $html = str_replace('>', '&gt;', $html);
    $html = str_replace('&emsp;', '', $html);
    $html = str_replace('&nbsp;', '', $html);
    $html = str_replace("\t", '', $html);
    while (true) {
        if (stripos($html, '  ') === false) {
            break;
        } else {
            $html = str_replace('  ', ' ', $html);
        }
    }
    return $html;
}

/**
 * 字符串截取，超过字数后以增加...
 * @param $str
 * @param int $length
 * @param string $addtext
 * @return string
 */
function str_cut_addtext($str, $length = 10, $addtext = '...')
{
    return Coduo\PHPHumanizer\StringHumanizer::truncateHtml($str, $length, '<b><i><u><em><strong><a><span>', $addtext);
}


/**
 * 去除BOM
 * @param string $string
 * @return false|string
 */
function str_remove_utf8_bom($string)
{
    if (substr($string, 0, 3) == pack('CCC', 239, 187, 191)) return substr($string, 3);
    return $string;
}

/**
 * 获取实例化后的拼音库
 * @return mixed|\Overtrue\Pinyin\Pinyin|string
 */
function get_pinyin_lib()
{
    $pinyin = getGlobals("PinyinLib");
    if (!$pinyin) {
        $pinyin = new \Overtrue\Pinyin\Pinyin('Overtrue\Pinyin\MemoryFileDictLoader');
        setGlobals("PinyinLib", $pinyin);
    }
    return $pinyin;
}

/**
 * 获取汉字的全拼
 * @param $_String
 * @return string
 */
function pinyin_permalink($_String)
{
    $pinyin = get_pinyin_lib();
    return $pinyin->permalink($_String, '');
}